#!/usr/bin/env bash
# vim: fdm=marker fmr=[[[,]]] cms=\ #%s

[[ -z $SOAR ]] && SOAR=/opt/soar
PATH=$PATH:$SOAR/common/bash/soar
. soar.sh

genmysql()
{ #[[[
    local svr=$1

    # svr.def
    cat >svr.def <<'EOD'
DB = mysql
SRCS = SVC.c
SVCS = SVC
OBJS =
LIBS =
EOD

    # svr.h
    cat >svr.h <<'EOD'
#ifndef __SVR_H__
#define __SVR_H__

#include <svr_skeleton.h>
#include <svcenv.h>

__BEGIN_DECLS

extern MYSQLC *dbconns;

__END_DECLS

#endif
EOD

    # svr.c
    cat >svr.c <<'EOD'
#include "svr.h"

MYSQLC *dbconns;

int svr_init(char *passwd)
{/*{{{*/
    char buf[200];
    int res;

    mysqlc_init();
    ALLOC_MULTI_DOERR(dbconns, MYSQLC, cnfg_info.start,
            sprintf(buf, "%s: alloc dbconns fail", SERVER_NAME);
            fprintf(stderr, "%s\n", buf); errlog(buf);
            return(-1);
            );
    int thrd_idx;     
    for(thrd_idx=0; thrd_idx<cnfg_info.start; ++thrd_idx)
    {   
        res=mysqlc_connect_ex(
                cnfg_info._db_.user,
                passwd,
                cnfg_info._db_.database,
                cnfg_info._db_.host, 
                NULL,
                &dbconns[thrd_idx]);
        if(res != MY_OK)
        {
            sprintf(buf, "%s: thrd(%d) connect to db fail, res:%d",
                    SERVER_NAME, thrd_idx, res);
            fprintf(stderr, "%s\n", buf); errlog(buf);
            return(-1);
        }
    }

    return(0);
}/*}}}*/

int svr_done()
{/*{{{*/
    int res;

    int thrd_idx;
    for(thrd_idx=0; thrd_idx<cnfg_info.start; ++thrd_idx)
    {   
        res=mysqlc_disconnect_ex(dbconns[thrd_idx]);
        if(res != MY_OK)
        {
            errlog("%s: thrd(%d) disconnect from db fail, res:%d",
                    SERVER_NAME, thrd_idx, res);
        }
    }
    return(0);
}/*}}}*/
EOD

    # SVC.c
    cat >SVC.c <<'EOD'
#include "svr.h"

int SVC_FUNC_SVC(int thrd_idx, char *request, char *respond)
{/*{{{*/
    MYSQLC db=dbconns[thrd_idx];
    int res;

    char para_desc[200];
    PARA para;
    sprintf(para_desc,
            "uuid(string:3-%d)",
            UUID_SIZE);
    res=para_load(request, para_desc, &para);
    if(res)
    {
        if(res > 0)
            errlog("%s: (%.20s) no.%d para invalid",
                    __func__, request, res);
        else
            errlog("%s: para_load fail, res:%d",
                    __func__, res);
        RETURN_ERR_PARA;
    }
    char uuid[UUID_SIZE+1];
    para_copy_by_name(para, "uuid", uuid);
    trim_tail_space_notnull(uuid);
    para_free(para);

    char sql[200];
    struct dbc_rset rset;
    sprintf(sql,
            "select loginname,nickname,login_times from memb_info "
            "where uuid='%s'",
            uuid);
    res=mysqlc_query_ex(db, sql, 1, &rset);
    if(res != MY_OK && res != MY_NO_DATA_FOUND)
    {
        errlog("%s: mysqlc_query fail, res:%d",
                __func__, res);
        RETURN_ERR_DB;
    }
    char loginname[LOGINNAME_SIZE+1];
    char nickname[NICKNAME_SIZE+1];
    int login_times;
    if(res == MY_NO_DATA_FOUND)
    {
        errlog("%s: mysqlc_query %s not found",
                __func__, uuid);
        para_put_item(respond, SOAR_ERR_OK);
    }
    else
    {
        dbc_col_export_char(&rset, 0, 0, loginname); 
        dbc_col_export_char(&rset, 0, 1, nickname); 
        login_times=dbc_col_export_int(&rset, 0, 2); 
        dbc_query_free(&rset);
        para_put_item(respond, SOAR_ERR_OK);
        para_put_item(respond, uuid);
        para_put_item(respond, loginname);
        para_put_item(respond, nickname);
        para_put_item_int(respond, login_times);
    }

    return(0);
}/*}}}*/
EOD
} #]]]

genoracle()
{ #[[[
    local svr=$1

    # svr.def
    cat >svr.def <<'EOD'
DB = mysql
SRCS = SVC.c
SVCS = SVC
OBJS =
LIBS =
EOD

    # svr.h
    cat >svr.h <<'EOD'
#ifndef __SVR_H__
#define __SVR_H__

#include <svr_skeleton.h>
#include <svcenv.h>

__BEGIN_DECLS

extern ORAPROC *dbconns;

__END_DECLS

#endif
EOD

    # svr.c
    cat >svr.c <<'EOD'
#include "svr.h"

ORAPROC *dbconns;

int svr_init(char *passwd)
{/*{{{*/
    char buf[200];
    int res;

    oraproc_init();
    ALLOC_MULTI_DOERR(dbconns, ORAPROC, cnfg_info.start,
            sprintf(buf, "%s: alloc dbconns fail", SERVER_NAME);
            fprintf(stderr, "%s\n", buf); errlog(buf);
            return(-1);
            );
    int thrd_idx;     
    for(thrd_idx=0; thrd_idx<cnfg_info.start; ++thrd_idx)
    {   
        res=oraproc_connect_ex(
                cnfg_info._db_.user,
                passwd,
                cnfg_info._db_.host,
                &dbconns[thrd_idx]);
        if(res != ORA_OK)
        {
            sprintf(buf, "%s: thrd(%d) connect to db fail, res:%d",
                    SERVER_NAME, thrd_idx, res);
            fprintf(stderr, "%s\n", buf); errlog(buf);
            return(-1);
        }
    }

    return(0);
}/*}}}*/

int svr_done()
{/*{{{*/
    int res;

    int thrd_idx;
    for(thrd_idx=0; thrd_idx<cnfg_info.start; ++thrd_idx)
    {   
        res=oraproc_disconnect_ex(dbconns[thrd_idx]);
        if(res != ORA_OK)
        {
            errlog("%s: thrd(%d) disconnect from db fail, res:%d",
                    SERVER_NAME, thrd_idx, res);
        }
    }
    return(0);
}/*}}}*/
EOD

    # SVC.c
    cat >SVC.c <<'EOD'
#include "svr.h"

int SVC_FUNC_SVC(int thrd_idx, char *request, char *respond)
{/*{{{*/
    ORAPROC db=dbconns[thrd_idx];
    int res;

    char para_desc[200];
    PARA para;
    sprintf(para_desc,
            "uuid(string:3-%d)",
            UUID_SIZE);
    res=para_load(request, para_desc, &para);
    if(res)
    {
        if(res > 0)
            errlog("%s: (%.20s) no.%d para invalid",
                    __func__, request, res);
        else
            errlog("%s: para_load fail, res:%d",
                    __func__, res);
        RETURN_ERR_PARA;
    }
    char uuid[UUID_SIZE+1];
    para_copy_by_name(para, "uuid", uuid);
    trim_tail_space_notnull(uuid);
    para_free(para);

    char sql[200];
    struct dbc_rset rset;
    struct dbc_bind bind;
    sprintf(sql,
            "select loginname,nickname,login_times from memb_info "
            "where uuid=:0");
    dbc_bind_char(&bind, 0, uuid);
    res=oraproc_query_ex(db, &bind, 1, sql, 1, &rset);
    if(res != ORA_OK && res != ORA_NO_DATA_FOUND)
    {
        errlog("%s: db query fail, res:%d",
                __func__, res);
        RETURN_ERR_DB;
    }
    char loginname[LOGINNAME_SIZE+1];
    char nickname[NICKNAME_SIZE+1];
    int login_times;
    if(res == ORA_NO_DATA_FOUND)
    {
        errlog("%s: db query %s not found",
                __func__, uuid);
        para_put_item(respond, SOAR_ERR_OK);
    }
    else
    {
        dbc_col_export_char(&rset, 0, 0, loginname); 
        dbc_col_export_char(&rset, 0, 1, nickname); 
        login_times=dbc_col_export_int(&rset, 0, 2); 
        dbc_query_free(&rset);
        para_put_item(respond, SOAR_ERR_OK);
        para_put_item(respond, uuid);
        para_put_item(respond, loginname);
        para_put_item(respond, nickname);
        para_put_item_int(respond, login_times);
    }

    return(0);
} /*}}}*/
EOD
} #]]]

main()
{ #[[[
    if [[ -z $SVCENV_DIR ]]
    then
        echo "Error: SVCENV_DIR not set"
        return 1
    fi
    if [[ -z $SVCENV_CNFG ]]
    then
        echo "Error: SVCENV_CNFG not set"
        return 1
    fi

    local svr
    read -p "Server name: " svr
    if [[ -z $svr ]]
    then
        echo "Error: server name invalid"
        return 1
    fi
    if [[ -e $svr ]]
    then
        echo "Error: $svr found"
        return 1
    fi
    mkdir $svr
    if (( $? != 0 ))
    then
        echo "Error: create $svr directory fail"
        return 1
    fi
    cd $svr

    local option
    read -p "\
Database type:
    1) mysql
    2) oracle
Choose[1]: " option
    option=${option:=1} 
    case $option in
    1) genmysql $server_name ;;
    2) genoracle $server_name ;;
    *)
        echo "Error: option invalid"
        return 1
    esac
    if (( $? != 0 ))
    then
        echo "Error: generate code fail"
        return 1
    fi
} #]]]

OS=$(uname | tr '[:upper:]' '[:lower:]')
CPU=$(uname -m | tr '[:upper:]' '[:lower:]')

main $@
exit $?
